package com.example.finalhomework.musicplayer

import android.app.Application
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.MediaPlayer
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.util.Log
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.core.app.NotificationCompat
import com.example.finalhomework.MainActivity
import com.example.finalhomework.R

// 音乐播放器的 ViewModel 类，继承自 AndroidViewModel
class MusicPlayerViewModel(application: Application, private val savedStateHandle: SavedStateHandle) : AndroidViewModel(application) {
    var mediaPlayer: MediaPlayer? = null // 媒体播放器对象
    var isPlaying by mutableStateOf(savedStateHandle.get<Boolean>("isPlaying") ?: false) // 是否正在播放
    var trackList by mutableStateOf(savedStateHandle.get<List<String>>("trackList") ?: listOf()) // 音乐列表
    var currentTrackName by mutableStateOf(savedStateHandle.get<String>("currentTrackName") ?: "") // 当前播放的音乐名称
    var currentMusicName by mutableStateOf(savedStateHandle.get<String>("currentMusicName") ?: "") // 当前播放的音乐文件名
    var progress by mutableStateOf(savedStateHandle.get<Float>("progress") ?: 0f) // 播放进度
    var currentTrackIndex by mutableStateOf(savedStateHandle.get<Int>("currentTrackIndex") ?: 0) // 当前播放的音乐索引

    private val handler = Handler(Looper.getMainLooper()) // 主线程的 Handler
    private val updateProgressTask = object : Runnable { // 更新播放器进度条的任务
        override fun run() {
            updateProgress() // 更新进度条
            handler.postDelayed(this, 1000) // 每秒更新一次
        }
    }

    init {
        if (isPlaying) {
            handler.post(updateProgressTask) // 如果正在播放，开始更新进度
        }
        Log.d("MusicPlayerViewModel", "ViewModel initialized with isPlaying: $isPlaying, currentTrackIndex: $currentTrackIndex")
    }

    // 加载音乐文件
    fun loadMusicFiles(context: Context) {
        viewModelScope.launch {
            trackList = withContext(Dispatchers.IO) {
                val mp3Files = mutableListOf<String>()
                val projection = arrayOf(
                    MediaStore.Audio.Media.DATA,
                    MediaStore.Audio.Media.DISPLAY_NAME
                )
                val selection = "${MediaStore.Audio.Media.MIME_TYPE} = ?"
                val selectionArgs = arrayOf("audio/mpeg")
                val sortOrder = "${MediaStore.Audio.Media.DATE_ADDED} DESC"

                context.contentResolver.query(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    projection,
                    selection,
                    selectionArgs,
                    sortOrder
                )?.use { cursor ->
                    val dataColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)
                    while (cursor.moveToNext()) {
                        val filePath = cursor.getString(dataColumn)
                        mp3Files.add(filePath)
                    }
                }
                mp3Files
            }
            if (trackList.isNotEmpty()) {
                currentTrackName = trackList[currentTrackIndex] // 设置当前播放的音乐名称
                currentMusicName = File(trackList[currentTrackIndex]).name // 设置当前播放的音乐文件名
                Log.d("MusicPlayerViewModel", "Loaded music files, currentTrackName: $currentTrackName, currentMusicName: $currentMusicName")
            }
        }
    }

    // 获取当前音乐信息
    fun getCurrentMusicInfo(): Pair<String, Float> {
        return if (isPlaying && trackList.isNotEmpty()) {
            val currentMusicName = File(trackList[currentTrackIndex]).name // 获取当前音乐文件名
            val progress = mediaPlayer?.currentPosition?.toFloat()?.div(mediaPlayer?.duration?.toFloat() ?: 1f) ?: 0f // 计算播放进度
            Log.d("MusicPlayerViewModel", "Current music info - Name: $currentMusicName, Progress: $progress")
            Pair(currentMusicName, progress) // 返回音乐文件名和播放进度
        } else {
            Pair("", 0f) // 如果没有播放，返回空字符串和0进度
        }
    }

    // 播放下一首音乐
    fun playNextTrack() {
        if (trackList.isNotEmpty()) {
            releaseMediaPlayer() // 释放当前的媒体播放器
            currentTrackIndex = (currentTrackIndex + 1) % trackList.size // 更新当前播放的音乐索引
            mediaPlayer = MediaPlayer.create(getApplication(), Uri.parse(trackList[currentTrackIndex])) // 创建新的媒体播放器
            mediaPlayer?.setOnCompletionListener {
                playNextTrack() // 设置播放完成监听器，播放下一首
            }
            mediaPlayer?.start() // 开始播放
            isPlaying = true // 设置播放状态为 true
            currentMusicName = File(trackList[currentTrackIndex]).name // 更新当前播放的音乐文件名
            handler.post(updateProgressTask) // 开始更新进度
            showNotification(currentMusicName) // 显示通知
            Log.d("MusicPlayerViewModel", "Playing next track: $currentMusicName")
        }
    }

    // 释放媒体播放器
    fun releaseMediaPlayer() {
        mediaPlayer?.release() // 释放媒体播放器资源
        mediaPlayer = null // 将媒体播放器置为 null
        handler.removeCallbacks(updateProgressTask) // 移除更新进度的��务
        cancelNotification() // 取消通知
        Log.d("MusicPlayerViewModel", "MediaPlayer released")
    }

    // 更新进度
    fun updateProgress() {
        mediaPlayer?.let {
            progress = it.currentPosition / it.duration.toFloat() // 计算播放进度
            Log.d("MusicPlayerViewModel", "Progress updated: $progress") // 打印日志
        }
    }

    // 开始更新进度
    fun startUpdatingProgress() {
        handler.post(updateProgressTask) // 开始更新进度
        Log.d("MusicPlayerViewModel", "Started updating progress")
    }

    // 停止更新进度
    fun stopUpdatingProgress() {
        handler.removeCallbacks(updateProgressTask) // 停止更新进度
        Log.d("MusicPlayerViewModel", "Stopped updating progress")
    }

    // 重置播放器
    override fun onCleared() {
        super.onCleared()
        releaseMediaPlayer() // 释放媒体播放器资源
        savedStateHandle["isPlaying"] = isPlaying // 保存播放状态
        savedStateHandle["trackList"] = trackList // 保存音乐列表
        savedStateHandle["currentTrackName"] = currentTrackName // 保存当前播放的音乐名称
        savedStateHandle["currentMusicName"] = currentMusicName // 保存当前播放的音乐文件名
        savedStateHandle["progress"] = progress // 保存播放进度
        savedStateHandle["currentTrackIndex"] = currentTrackIndex // 保存当前播放的音乐索引
        handler.removeCallbacks(updateProgressTask) // 移除更新进度的任务
        Log.d("MusicPlayerViewModel", "ViewModel cleared")
    }

    // 显示通知
    fun showNotification(musicName: String) {
        val context = getApplication<Application>().applicationContext
        val intent = Intent(context, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK // 设置 Intent 标志
        }
        val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) // 创建 PendingIntent

        // 使用 NotificationCompat.Builder 创建通知
        val notification = NotificationCompat.Builder(context, "MUSIC_PLAYER_CHANNEL")
            .setSmallIcon(R.drawable.baseline_music) // 设置小图标
            .setContentTitle("Now Playing Music") // 设置通知标题
            .setContentText(musicName) // 设置通知内容
            .setPriority(NotificationCompat.PRIORITY_LOW) // 设置通知优先级
            .setContentIntent(pendingIntent) // 设置点击通知时的操作
            .setOngoing(true) // 设置通知为持续状态
            .build()

        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(1, notification) // 显示通知
        Log.d("MusicPlayerViewModel", "Notification shown for music: $musicName")
    }

    // 取消通知
    private fun cancelNotification() {
        val context = getApplication<Application>().applicationContext
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.cancel(1) // 取消通知
        Log.d("MusicPlayerViewModel", "Notification cancelled")
    }

    // 暂停音乐
    fun pauseMusic() {
        mediaPlayer?.pause() // 暂停播放
        isPlaying = false // 设置播放状态为 false
        stopUpdatingProgress() // 停止更新进度
        cancelNotification() // 取消通知
        Log.d("MusicPlayerViewModel", "Music paused: $currentMusicName")
    }

    // 停止音乐
    fun stopMusic() {
        mediaPlayer?.stop() // 调用 stop() 方法后，必须调用 prepare 或 prepareAsync 方法重新准备音频资源
        mediaPlayer?.reset() // 调用 reset() 方法后，MediaPlayer 将释放所有资源，需要重新设置数据源并准备音频资源才能再次使用
        mediaPlayer = null // 将 mediaPlayer 置为 null
        releaseMediaPlayer() // 释放媒体播放器资源
        isPlaying = false // 设置播放状态为 false
        stopUpdatingProgress() // 停止更新进度
        cancelNotification() // 取消通知
        Log.d("MusicPlayerViewModel", "Music stopped: $currentMusicName")
    }
}